Skip to content

rust: store local wrapper addresses in async stream/future vtables - #1699

Merged
alexcrichton merged 5 commits into
bytecodealliance:mainfrom
alexcrichton:fix-dylib-bindings
Aug 27, 2026
Merged

rust: store local wrapper addresses in async stream/future vtables #1699
alexcrichton merged 5 commits into
bytecodealliance:mainfrom
alexcrichton:fix-dylib-bindings

Conversation

@alexcrichton

Copy link
Copy Markdown
Member

Under a position-independent dynamic library build, an intrinsic that is
only address-taken (stored in the StreamVtable/FutureVtable, never called
by name) is lowered by LLVM to a GOT.func global keyed by its mangled Rust
symbol, and the canonical (module, field) wasm import is dropped. The
component linker resolves GOT.func slots against library exports, but no
library exports that mangled symbol and the canonical name is gone, so
components using dynamic libraries fail to link.

Emit a local wrapper for each of the intrinsics on wasm and store the
wrapper's address in the vtable. The wrapper calls the canonical import
by name (keeping the import live) and the address-take becomes an
ordinary table relocation against a defined function, which the linker
resolves.

alexcrichton and others added 2 commits August 26, 2026 15:13
This is in preparation to try to test and expose a bug in the toolchain
in a subsequent commit and fix it.
Under a position-independent dynamic library build, an intrinsic that is
only address-taken (stored in the StreamVtable/FutureVtable, never called
by name) is lowered by LLVM to a GOT.func global keyed by its mangled Rust
symbol, and the canonical (module, field) wasm import is dropped. The
component linker resolves GOT.func slots against library exports, but no
library exports that mangled symbol and the canonical name is gone, so
components using dynamic libraries fail to link.

Emit a local wrapper for each of the intrinsics on wasm and store the
wrapper's address in the vtable. The wrapper calls the canonical import
by name (keeping the import live) and the address-take becomes an
ordinary table relocation against a defined function, which the linker
resolves.
@alexcrichton
alexcrichton requested a review from dicej August 26, 2026 22:22
Comment thread crates/test/src/rust.rs
#[serde(default)]
externs: Vec<String>,

#[serde(default)]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably have a doc comment since the other fields do.

Comment thread crates/test/src/lib.rs Outdated
bail!("{error}")
}

/// TODO

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO as in later or TODO as in for this PR?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, no this is just "TODO alex fix this before making a PR" which I pretty consistently always forget to do...

@alexcrichton
alexcrichton enabled auto-merge August 27, 2026 14:26
@alexcrichton
alexcrichton added this pull request to the merge queue Aug 27, 2026
Merged via the queue into bytecodealliance:main with commit d6bc3a0 Aug 27, 2026
30 checks passed
@alexcrichton
alexcrichton deleted the fix-dylib-bindings branch August 27, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants